package lesson03;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.BindException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

public class TCPEochServer02 {
    private ServerSocket socket;

    public TCPEochServer02(int port) throws IOException {
        if (port < 1024 || port > 65535) {
            throw new BindException("端口号需要在1024 - 65535之间");
        }
        socket = new ServerSocket(port);   //自动分配id，获取端口号是多少
    }

    public void start() throws IOException {
        System.out.println("服务器启动，等待客户端连接.");
        while (true) {
            Socket Clientaccept = socket.accept();   //这一行已经获取了客户端的端口号与ip地址，返回给Clientaccept
            System.out.printf("[%s:%d] 客户端已上线.\n", Clientaccept.getInetAddress().toString(), Clientaccept.getPort());
            processTCPEchoServer(Clientaccept);
        }

    }

    private void processTCPEchoServer(Socket clientaccept) {
        try (InputStream inputStream = clientaccept.getInputStream();  //通过clientaccept创建输入流与输出流自动获取客户端与服务端ip与端口号
             OutputStream outputStream = clientaccept.getOutputStream()) {
            while (true) {
                //1.写一个Scanner来接收客户端发来的数据
                Scanner scanner = new Scanner(inputStream);//通过流来接收
                if (!scanner.hasNextLine()) {
                    System.out.printf("[%s:%d] 客户端已下线.\n", clientaccept.getInetAddress().toString(), clientaccept.getPort());
                    break;
                }
                String request = scanner.nextLine();  //获取客户端输入的一行数据
                String response = process(request);   //获取到数据以后进行处理数据
                //处理完数据以后写回客户端
                PrintWriter printWriter = new PrintWriter(outputStream);  //将输出流封装起来方便写入
                printWriter.println(response);                            //直接写入网卡里面，我们封装了printWriter，此时他知道客户端与服务器的ip与端口号
                printWriter.flush();                                       //刷新网卡里面的数据发送到客户端
                System.out.printf("[%s:%d] request = %s  response = %s\n", clientaccept.getInetAddress().toString(),
                        clientaccept.getPort(), request, response);

            }

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    protected String process(String request) {
        return request;
    }


    public static void main(String[] args) throws IOException {
        TCPEochServer02 tcpEochServer02 = new TCPEochServer02(9090);
        tcpEochServer02.start();
    }

}
